package com.ali.util;

import com.ali.exception.ServiceException;

import java.math.BigDecimal;

/**
 * 计算相关工具类(针对double类型，在项目中用到小数类型的请使用BigDecimal类型)
 *
 * @author jack.wu
 * @version 1.0
 * @date 2020/8/19
 */
public class CalculatorUtils {

    /**
     * 精确的double类型加法运算
     *
     * @param v1 值1
     * @param v2 值2
     * @return 相加后的结果
     */
    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 精确的double类型减法运算
     *
     * @param v1 值1
     * @param v2 值2
     * @return 相减后的结果
     */
    public static double sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 精确的double类型乘法法运算
     *
     * @param v1 值1
     * @param v2 值2
     * @return 乘法运算之后的结果
     */
    public static double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 精确的double类型除法运算
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 精度
     * @return 除法运算之后的结果
     */
    public static double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new ServiceException("Accuracy cannot be less than 0");
        }
        BigDecimal b1 = new BigDecimal(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 精确的小数位四舍五入处理
     *
     * @param v     值
     * @param scale 精度
     * @return 值的四舍五入
     */
    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new ServiceException("Accuracy cannot be less than 0");
        }
        BigDecimal b = new BigDecimal(String.valueOf(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 精确的比较大小
     *
     * @param v1 值1
     * @param v2 值2
     * @return 1 v1>v2   0 v1=v2   -1 v1<v2
     */
    public static int compareTo(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.compareTo(b2);
    }

    private CalculatorUtils() {
    }

}
